﻿using System;
using System.Collections.Generic;

namespace DimensionsHelper.Common.Contracts.Metadata;
// 完整脚本示例：
// 
// style(
//     Color = "Blue",
//     BgColor = "blue",
//     Hidden = false,
//     Align = "Center",
//     VerticalAlign = "Super",
//     ElementAlign = "NewLine",
//     Indent = 3,
//     ZIndex = 3,
//     Cursor = "SEResize",
//     ImagePosition = "Left",
//     Orientation = "Row",
//     Columns = 2,
//     Rows = 3,
//     Width = "4in",
//     Height = "23%",
//     Control(
//         Type = "Password",
//         ReadOnly = false,
//         Accelerator = "R"
//     ),
//     Cell(
//         Width = "2",
//         Height = "1. 234 PX",
//         BorderColor = "blue",
//         BorderTopColor = "yellow",
//         BorderRightColor = "white",
//         BorderBottomColor = "blue",
//         BorderLeftColor = "black",
//         BorderStyle = "Double",
//         BorderWidth = 11,
//         BorderTopWidth = 10,
//         BorderRightWidth = 12,
//         BorderBottomWidth = 1,
//         BorderLeftWidth = 23,
//         BorderTopStyle = "Inset",
//         BorderRightStyle = "Ridge",
//         BorderBottomStyle = "Double",
//         BorderLeftStyle = "Solid",
//         Padding = 2,
//         PaddingTop = 1,
//         PaddingRight = 2,
//         PaddingBottom = 1,
//         PaddingLeft = 2,
//         Wrap = false,
//         ColSpan = 1,
//         RowSpan = 1,
//         BgColor = "blue",
//         RepeatHeader = 0
//     ),
//     Font(
//         Family = "arial",
//         Size = 3,
//         IsUnderline = true,
//         IsItalic = false,
//         IsBold = true,
//         IsStrikethrough = true,
//         IsOverline = false,
//         IsBlink = true,
//         IsSuperscript = false,
//         IsSubscript = false
//     )
// ),
// <Styles> ::= ( [ AreaName: ] style ( <property> (, <property> )* ) )*

/// <summary>
///     ControlStyle对象中使用的边框样式配置。
/// </summary>
[MetadataFlag(MetadataScriptSerializeType.Name)]
public enum BorderStyles
{
    None,
    Double,
    Grove,
    Inset,
    Outset,
    Ridge,
    Solid
}

/// <summary>
///     ControlStyle对象中使用的空间样式配置
/// </summary>
[MetadataFlag(MetadataScriptSerializeType.Name)]
public enum ControlTypes
{
    Static,
    Edit,
    SingleLineEdit,
    MultiLineEdit,
    DropList,
    ComboList,
    RadioButton,
    CheckButton,
    ListBox,
    ListControl,
    Button,
    Date,
    Time,
    DateTime,
    Password,
    XML
}

/// <summary>
///     ControlStyle对象中使用的横向对齐样式。
/// </summary>
[MetadataFlag(MetadataScriptSerializeType.Name)]
public enum HorizontalAlignments
{
    Default,
    Left,
    Center,
    Right,
    Justify
}

/// <summary>
///     ControlStyle对象中使用的指针样式。
/// </summary>
[MetadataFlag(MetadataScriptSerializeType.Name)]
public enum CursorTypes
{
    Auto,
    CrossHair,
    Default,
    Pointer,
    Move,
    EResize,
    NEResize,
    NResize,
    NWResize,
    WResize,
    SWResize,
    SResize,
    SEResize,
    Text,
    Wait,
    Help
}

/// <summary>
///     ControlStyle对象中使用的元素对齐样式
/// </summary>
[MetadataFlag(MetadataScriptSerializeType.Name)]
public enum ElementAlignments
{
    Default,
    Right,
    NewLine
}

/// <summary>
///     ControlStyle对象中使用的排列方向配置。
/// </summary>
[MetadataFlag(MetadataScriptSerializeType.Name)]
public enum Orientations
{
    Default,
    Row,
    Column
}

/// <summary>
///     ControlStyle对象中使用的图片布局位置配置。
/// </summary>
[MetadataFlag(MetadataScriptSerializeType.Name)]
public enum ImagePositions
{
    Left,
    Right,
    Top,
    Bottom,
    ImageOnly,
    None
}

/// <summary>
///     ControlStyle对象中使用的纵向对齐设置。
/// </summary>
[MetadataFlag(MetadataScriptSerializeType.Name)]
public enum VerticalAlignments
{
    Default,
    Baseline,
    Middle,
    Sub,
    Super,
    TextTop,
    TextBottom,
    Top,
    Bottom
}

/// <summary>
///     音频空间位置。
/// </summary>
[MetadataFlag(MetadataScriptSerializeType.Name)]
public enum AudioControlPositions
{
    Left,
    Right,
    Top,
    Bottom
}

/// <summary>
///     录制模式
/// </summary>
[MetadataFlag(MetadataScriptSerializeType.Name)]
public enum RecordModes
{
    None,
    Manual,
    Auto,
    Prohibited
}

/// <summary>
///     存储MDM文档或MDM对象的控件样式设置。
/// </summary>
public class ControlStyle
{
    /// <summary>
    ///     控件类型。
    /// </summary>
    public ControlTypes? Type { get; set; }

    /// <summary>
    ///     控件是否只读。
    /// </summary>
    public bool? ReadOnly { get; set; }

    /// <summary>
    ///     控件加速配置。
    /// </summary>
    public string? Accelerator { get; set; }
}

/// <summary>
///     单元格样式配置。
/// </summary>
public class CellStyle
{
    /// <summary>
    ///     单元格宽度，可以是数字或者像素值。忽略时为 null。
    /// </summary>
    public string? Width { get; set; }

    /// <summary>
    ///     单元格高度，可以是数字或者像素值。忽略时为 null。
    /// </summary>
    public string? Height { get; set; }

    /// <summary>
    ///     边框颜色。
    /// </summary>
    public string? BorderColor { get; set; }

    /// <summary>
    ///     顶边框颜色。
    /// </summary>
    public string? BorderTopColor { get; set; }

    /// <summary>
    ///     左边框颜色。
    /// </summary>
    public string? BorderLeftColor { get; set; }

    /// <summary>
    ///     右边框颜色。
    /// </summary>
    public string? BorderRightColor { get; set; }

    /// <summary>
    ///     底边框颜色。
    /// </summary>
    public string? BorderBottomColor { get; set; }

    /// <summary>
    ///     边框样式。
    /// </summary>
    public BorderStyles? BorderStyle { get; set; }

    /// <summary>
    ///     左边框样式。
    /// </summary>
    public BorderStyles? BorderLeftStyle { get; set; }

    /// <summary>
    ///     右边框样式。
    /// </summary>
    public BorderStyles? BorderRightStyle { get; set; }

    /// <summary>
    ///     顶边框样式。
    /// </summary>
    public BorderStyles? BorderTopStyle { get; set; }

    /// <summary>
    ///     底边框样式。
    /// </summary>
    public BorderStyles? BorderBottomStyle { get; set; }

    /// <summary>
    ///     边框宽度。
    /// </summary>
    public double? BorderWidth { get; set; }

    /// <summary>
    ///     顶边框宽度。
    /// </summary>
    public double? BorderTopWidth { get; set; }

    /// <summary>
    ///     左边框宽度。
    /// </summary>
    public double? BorderLeftWidth { get; set; }

    /// <summary>
    ///     右边框宽度。
    /// </summary>
    public double? BorderRightWidth { get; set; }

    /// <summary>
    ///     底边框宽度。
    /// </summary>
    public double? BorderBottomWidth { get; set; }

    /// <summary>
    ///     向内缩进量。
    /// </summary>
    public double? Padding { get; set; }

    /// <summary>
    ///     左向内向缩进量。
    /// </summary>
    public double? PaddingLeft { get; set; }

    /// <summary>
    ///     右向内向缩进量。
    /// </summary>
    public double? PaddingRight { get; set; }

    /// <summary>
    ///     顶部内向缩进量。
    /// </summary>
    public double? PaddingTop { get; set; }

    /// <summary>
    ///     底部内向缩进量。
    /// </summary>
    public double? PaddingBottom { get; set; }

    /// <summary>
    ///     是否自动换行。
    /// </summary>
    public bool? Wrap { get; set; }

    /// <summary>
    ///     跨列数。
    /// </summary>
    public int? ColSpan { get; set; }

    /// <summary>
    ///     跨行数。
    /// </summary>
    public int? RowSpan { get; set; }

    /// <summary>
    ///     背景颜色。
    /// </summary>
    public string? BgColor { get; set; }

    /// <summary>
    ///     列头重复计数。
    /// </summary>
    public int? RepeatHeader { get; set; }

    /// <summary>
    ///     侧向行头重复计数。
    /// </summary>
    public int? RepeatSideHeader { get; set; }
}


/// <summary>
///     指示字体样式的各种效果，每个值占用一位二进制。
/// </summary>
[Flags]
public enum FontStyleEffects
{
    IsUnderline = 1 << 0,
    IsItalic = 1 << 1,
    IsBold = 1 << 2,
    IsStrikethrough = 1 << 3,
    IsOverline = 1 << 4,
    IsBlink = 1 << 5,
    IsSuperscript = 1 << 6,
    IsSubscript = 1 << 7
}


/// <summary>
///     字体样式
/// </summary>
public class FontStyle
{
    /// <summary>
    ///     字体名。
    /// </summary>
    public string? Family { get; set; }

    /// <summary>
    ///     字号。
    /// </summary>
    public double? Size { get; set; }

    /// <summary>
    ///     是否添加下划线
    /// </summary>
    public bool IsUnderline { get; set; }

    /// <summary>
    ///     是否倾斜字体
    /// </summary>
    public bool IsItalic { get; set; }

    /// <summary>
    ///     是否加粗字体
    /// </summary>
    public bool IsBold { get; set; }

    /// <summary>
    ///     是否添加删除线
    /// </summary>
    public bool IsStrikethrough { get; set; }

    /// <summary>
    ///     是否添加上划线
    /// </summary>
    public bool IsOverline { get; set; }

    /// <summary>
    ///     是否闪烁
    /// </summary>
    public bool IsBlink { get; set; }

    /// <summary>
    ///     是否是上标
    /// </summary>
    public bool IsSuperscript { get; set; }

    /// <summary>
    ///     是否是下标
    /// </summary>
    public bool IsSubscript { get; set; }
}


public class AudioStyle
{
    /// <summary>
    ///     样式名
    /// </summary>
    public string? Name { get; set; }

    /// <summary>
    ///     音频播放器位置
    /// </summary>
    public AudioControlPositions? PlayControlPosition { get; set; } = null;

    /// <summary>
    ///     录制控件位置
    /// </summary>
    public AudioControlPositions? RecordControlPosition { get; set; } = null;

    /// <summary>
    ///     录制模式
    /// </summary>
    public RecordModes? RecordModes { get; set; } = null;
}

/// <summary>
///     存储MDM文档或MDM对象的样式设置。
/// </summary>
public class Style
{
    /// <summary>
    ///     当前样式所在的上下文类型。
    /// </summary>
    public string Context { get; set; } = string.Empty;

    /// <summary>
    ///     颜色名
    /// </summary>
    public string? Color { get; set; }

    /// <summary>
    ///     背景颜色
    /// </summary>
    public string? BgColor { get; set; }

    /// <summary>
    ///     是否隐藏
    /// </summary>
    public bool? IsHidden { get; set; }

    /// <summary>
    ///     当前元素的横向对齐样式
    /// </summary>
    public HorizontalAlignments? Align { get; set; }

    /// <summary>
    ///     当前元素的对齐样式
    /// </summary>
    public ElementAlignments? ElementAlign { get; set; }

    /// <summary>
    ///     当前元素的纵向对齐样式
    /// </summary>
    public VerticalAlignments? VerticalAlign { get; set; }

    /// <summary>
    ///     缩进量
    /// </summary>
    public int? Indent { get; set; }

    /// <summary>
    ///     垂直索引
    /// </summary>
    public int? ZIndex { get; set; }

    /// <summary>
    ///     鼠标指针样式
    /// </summary>
    public CursorTypes? Cursor { get; set; }

    /// <summary>
    ///     引用的图片路径。
    /// </summary>
    public string? Image { get; set; }

    /// <summary>
    ///     图片布局位置
    /// </summary>
    public ImagePositions? ImagePosition { get; set; }

    /// <summary>
    ///     内部元素排列顺序
    /// </summary>
    public Orientations? Orientation { get; set; }

    /// <summary>
    ///     列数
    /// </summary>
    public int? Columns { get; set; }

    /// <summary>
    ///     行数
    /// </summary>
    public int? Rows { get; set; }

    /// <summary>
    ///     控件宽度，可以是像素值。
    /// </summary>
    public string? Width { get; set; }

    /// <summary>
    ///     控件高度，可以是像素值
    /// </summary>
    public string? Height { get; set; }

    /// <summary>
    ///     单元格样式
    /// </summary>
    public CellStyle? Cell { get; set; }

    /// <summary>
    ///     控件样式
    /// </summary>
    public ControlStyle? Control { get; set; }

    /// <summary>
    ///     字体样式
    /// </summary>
    public FontStyle? Font { get; set; }

    /// <summary>
    ///     音频样式
    /// </summary>
    public AudioStyle? Audio { get; set; }
}


/// <summary>
///     存储不同上下文类型下的Style对象
/// </summary>
public interface IStyles : IMetadataObject, IEnumerable<Style>
{
    /// <summary>
    ///     获取指定索引的Style。
    /// </summary>
    /// <param name="index">指定索引</param>
    /// <returns>指定索引处的Style</returns>
    /// <exception cref="ArgumentOutOfRangeException" />
    Style this[int index] { get; }

    /// <summary>
    ///     当前集合中Style对象的数量。
    /// </summary>
    int Count { get; }

    /// <summary>
    ///     获取指定上下文类型的Style对象。
    /// </summary>
    /// <param name="context">指定上下文类型</param>
    /// <returns>已有的Style对象，如果给定上下文不存在，返回null</returns>
    Style? Get(string context);

    /// <summary>
    ///     获取指定上下文类型下的Style对象。
    /// </summary>
    /// <param name="context">指定上下文类型</param>
    /// <returns>如果指定上下文存在，返回已有Style，如果不存在，创建一个新的并返回</returns>
    Style GetOrAdd(string context);

    /// <summary>
    ///     设置指定上下文类型下的Style对象。
    /// </summary>
    /// <param name="context">指定上下文类型</param>
    /// <param name="style">新的Style</param>
    void Set(string context, Style style);
}